home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / viewers / prev / prev.lha / main.c < prev    next >
C/C++ Source or Header  |  1991-03-20  |  9KB  |  448 lines

  1. #include <stdio.h>
  2. #include <math.h>
  3. #ifdef VMS
  4. #include <types.h>
  5. #else
  6. #include <sys/types.h>
  7. #endif
  8. #ifdef MSC
  9. #include <fcntl.h>
  10. #include <string.h>
  11. #define rindex strrchr
  12. #else
  13. #ifdef SYSV
  14. #include <fcntl.h>
  15. #else
  16. #ifdef VMS
  17. #include <file.h>
  18. #else
  19. #include <sys/file.h>
  20. #endif
  21. #endif
  22. #endif
  23. #ifdef VMS
  24. #include <string.h>
  25. #define rindex strrchr
  26. #endif
  27. #ifdef MIPS
  28. #include <string.h>
  29. #define rindex strrchr
  30. #endif
  31. #ifdef TIME_STATS
  32. #include <sys/times.h>
  33. #endif
  34. #include <vogle.h>
  35. #include "art.h"
  36. #include "objs.h"
  37. #include "macro.h"
  38. #include "gram.h"
  39. #include "random.h"
  40.  
  41. extern char    *rindex();
  42. extern hlist    *trace();
  43. extern void    shade();
  44. extern time_t    time();
  45.  
  46. extern object    *treeinit();
  47.  
  48. #ifndef VMS
  49. FILE    *logfile = stdout;
  50. #else
  51. FILE    *logfile;
  52. #endif
  53.  
  54. int    linecount;        /* line counter for parser */
  55.  
  56. object    *oblist;        /* object list */
  57. object    *treeobjs, *otherobjs;    /* bsp-able and non-bsp-able objects */
  58.  
  59. light    *lights;        /* lights list */
  60.  
  61. symbol    *ostack[STACKSIZE],    /* object def stack */
  62.     **ostackp;
  63.  
  64. attr    astack[STACKSIZE],    /* attribute stack */
  65.     *astackp;
  66.  
  67. mats    mstack[STACKSIZE],    /* transformation stack */
  68.     *mstackp;
  69.  
  70. char    *title;            /* title of picture */
  71.  
  72. char    currentfile[MESLEN];    /* name of current "input" file */
  73.  
  74. int    raysperpix = 1;        /* number of rays per pixel */
  75. int    maxhitlevel = 6;    /* max number of rays traced in reflection */
  76. long    filetype = PIX_RLE;    /* output file format */
  77.  
  78. short    raynumber = 1;        /* initial raynumber */
  79.  
  80. float    screenx = 1.0,        /* half screen width */
  81.     screeny = 1.0;        /* half screen height */
  82.  
  83. float    tolerance;        /* tolerance value */
  84.  
  85. int    maxtreedepth = 35;    /* max depth for kd tree */
  86.  
  87. int    orthographic = FALSE;    /* orthographic or perspective projection */
  88.  
  89. /*
  90.  * ambient colour and background pixel stuff
  91.  */
  92. colour    ambient;
  93. colour    backcol = { 0.0, 0.0, 0.0 };
  94.  
  95. /*
  96.  * light falloff
  97.  */
  98. float    falloff = 0.0;
  99.  
  100. /*
  101.  * global refractive index
  102.  */
  103. float    ri = 1.0;
  104.  
  105. /*
  106.  * pointer to the free list for hit structures
  107.  */
  108. hlist    *fhlist;
  109.  
  110. /*
  111.  * details for the primary rays
  112.  */
  113. vector    org;
  114.  
  115. vector    viewup = { 0.0, 1.0, 0.0 };
  116.  
  117. matrix    trans = {
  118.     1.0, 0.0, 0.0, 0.0,
  119.     0.0, 1.0, 0.0, 0.0,
  120.     0.0, 0.0, 1.0, 0.0,
  121.     0.0, 0.0, 0.0, 1.0
  122. };
  123.  
  124. /*
  125.  * shading stack
  126.  */
  127. shadedata    *sstack, *sstackp;
  128.  
  129. /*
  130.  * haze stuff
  131.  */
  132. float    fogfactor = 0.0,        /* the fog factor */
  133.     rfactor = 0.03;            /* the mysterious "r" factor */
  134.  
  135.  
  136. colour    hazecolour = { 1.0, 1.0, 1.0 };    /* the haze colour */
  137.  
  138. float    sourceradius;        /* For ripple texture */
  139.  
  140. /*
  141.  * temporary file pointer
  142.  */
  143. char    *tmpname;
  144.  
  145. /*
  146.  * random number pointers
  147.  */
  148. float    *randp = randtable,
  149.     *erandp = &randtable[sizeof(randtable) / sizeof(float)];
  150.  
  151. /*
  152.  * function pointer tables for intersections, normals, etc...
  153.  */
  154. hlist    *(*intersects[NUM_OBJS])();
  155. void    (*normal[NUM_OBJS])();
  156. void    (*tilefun[NUM_OBJS])();
  157.  
  158. int    checkbbox[NUM_OBJS];    /* should we check bounding box of this type */
  159.  
  160. /*
  161.  * x, y offsets, scale, and sampleing
  162.  */
  163. static int    xoff, yoff;
  164. static float    xscale, yscale;
  165. static int    ysperpix, xsperpix;
  166.  
  167. /*
  168.  * frame id extension
  169.  */
  170. char    *frameid = "000";
  171.  
  172. /*
  173.  * default name
  174.  */
  175. char    *defname = "pic.pix";
  176.  
  177.  
  178. /*
  179.  * eyepoint stuff
  180.  */
  181. float    fov = 90.0;
  182. float    twist = 0.0;
  183. float    near = 1.0;
  184. vector    eye = { 0.0, 0.0, 1.0 };
  185. vector    ref = { 0.0, 0.0, 0.0 };
  186. int    lookatdone = FALSE;
  187.  
  188. /*
  189.  * antialiasing stuff
  190.  */
  191. int        pixelgrid = FALSE;    /* pixel grid on or off */
  192. static int    extrarays,          /* spare rays for jittering */
  193.         totrays;            /* total number of rays per pixel */
  194.  
  195. static pixel    *topline;       /* scanline of sample grid at top of current scanline */
  196.  
  197. static pixel    others[2];      /* bottom 2 samples of pixel grid */
  198.  
  199. static float    averagefactor;    /* number to divide final samples through by */
  200.                   
  201. int    longlines = 5;        /* number of longitudanal lines to be drawn */
  202. int    latlines = 5;        /* number of latitudanal lines to be drawn */
  203.  
  204. static int    totobjs;
  205.  
  206. /*
  207.  * usage
  208.  *
  209.  *    print out usage details for art.
  210.  */
  211. usage(s)
  212.     char    *s;
  213. {
  214.     if (s != (char *)NULL)
  215.         warning(s);
  216.  
  217.     fatal("usage: art [-v] file.scn x_res y_res [-x x1 x2] [-y y1 y2] [-f frameid] [-o outputname] [-n]\n");
  218. }
  219.  
  220. /*
  221.  * main driver
  222.  */
  223. main(ac, av)
  224.     int    ac;
  225.     char    *av[];
  226. {
  227.     int        y, x, chatty, indx, standardin, preprocess, nameset;
  228.     char        *p, name[BUFSIZ], buf[BUFSIZ];
  229.     image        *im;
  230.     FILE        *infile;
  231.     unsigned char    *red, *green, *blue, *alpha;
  232.     int        i, fragment, xsize, ysize, xstart, xend, ystart, yend;
  233.     object        *o, *nexto;
  234.     float        k1, k2;
  235.     expression    *e;
  236.  
  237.     if (ac < 4)
  238.         usage((char *)NULL);
  239.  
  240.     xsize = atoi(av[2]);
  241.     ysize = atoi(av[3]);
  242.  
  243.     xstart = 0;
  244.     xend = xsize - 1;
  245.  
  246.     ystart = ysize - 1;
  247.     yend = 0;
  248.  
  249.     preprocess = TRUE;
  250.     nameset = FALSE;
  251.     standardin = FALSE;
  252.     fragment = FALSE;
  253.                     /* check for other options */
  254.     for (i = 4; i < ac; i++) {
  255.         if (strcmp(av[i], "-y") == 0) {
  256.             if (av[i + 1] == (char *)NULL)
  257.                 usage("art: -y requires two numbers.\n");
  258.             if (av[i + 2] == (char *)NULL)
  259.                 usage("art: -y requires two numbers.\n");
  260.             ystart = ysize - atoi(av[i + 1]) - 1;
  261.             yend = ysize - atoi(av[i + 2]) - 1;
  262.             fragment = TRUE;
  263.             i += 2;
  264.         } else if (strcmp(av[i], "-x") == 0) {
  265.             if (av[i + 1] == (char *)NULL)
  266.                 usage("art: -x requires two numbers.\n");
  267.             if (av[i + 2] == (char *)NULL)
  268.                 usage("art: -x requires two numbers.\n");
  269.             xstart = atoi(av[i + 1]);
  270.             xend = atoi(av[i + 2]);
  271.             fragment = TRUE;
  272.             i += 2;
  273.         } else if (strcmp(av[i], "-f") == 0) {
  274.             if (av[i + 1] == (char *)NULL)
  275.                 usage("art: -f requires frame identifier.\n");
  276.             frameid = av[i + 1];
  277.             i += 1;
  278.         } else if (strcmp(av[i], "-o") == 0) {
  279.             if (av[i + 1] == (char *)NULL)
  280.                 usage("art: -o requires name.\n");
  281.             defname = av[i + 1];
  282.             nameset = TRUE;
  283.             i += 1;
  284.         } else if (strcmp(av[i], "-n") == 0) {
  285.             preprocess = FALSE;
  286.         } else {
  287.             sprintf(buf, "art: unknown option %s.\n", av[i]);
  288.             usage(buf);
  289.         }
  290.     }
  291.  
  292.     /*
  293.      * set up window
  294.      */
  295.     prefsize(xend - xstart + 1, ystart - yend + 1);
  296.  
  297.     vinit("");
  298.  
  299.     color(BLACK);
  300.     clear();
  301.  
  302.     color(WHITE);
  303.  
  304.     sourceradius = 100.0;
  305.  
  306.     mident4(mstack[0].om);
  307.     mident4(mstack[0].vm);
  308.     mident4(mstack[0].ray2obj);
  309.     mident4(mstack[0].obj2ray);
  310.     mstack[0].maxscale = 1.0;
  311.     mstack[0].nscales.x = mstack[0].nscales.y = mstack[0].nscales.z = 1.0;
  312.  
  313.     astack[0].s = (surface *)smalloc(sizeof(surface));
  314.     astack[0].s->falloff = astack[0].s->trans = astack[0].s->refl = 0.0;
  315.     astack[0].s->c.r = astack[0].s->c.g = astack[0].s->c.b = 1.0;
  316.     astack[0].s->a.r = astack[0].s->a.g = astack[0].s->a.b = 0.0;
  317.     astack[0].s->ri = astack[0].s->kd = 1.0;
  318.     astack[0].s->ks = 0.0;
  319.     astack[0].txtlist = (texture *)NULL;
  320.     astack[0].shadows = TRUE;
  321.     astack[0].slevel = 0;
  322.  
  323.     mstackp = mstack;
  324.     astackp = astack;
  325.     ostackp = ostack;
  326.  
  327.     linecount = 1;
  328.  
  329.     if (strcmp(av[1], "-") == 0)
  330.         standardin = TRUE;
  331.         
  332.     if (standardin || nameset) {
  333.         strcpy(name, defname);
  334.  
  335.         if ((p = rindex(name, '.')) == (char *)NULL)
  336.             fatal("art: output file should end with \".pix\".\n");
  337.     } else {
  338.         strcpy(name, av[1]);
  339.  
  340.         if ((p = rindex(name, '.')) == (char *)NULL)
  341.             fatal("art: input file should end with \".scn\".\n");
  342.         standardin = FALSE;
  343.     }
  344.  
  345.     strcpy(p, ".log");
  346.     if ((logfile = fopen(name, "w")) == NULL) {
  347.         sprintf(buf, "art: unable to open %s for writing.\n", name);
  348.         fatal(buf);
  349.     }
  350.  
  351.     if (!standardin) {
  352.         if (preprocess) {
  353.             strcpy(p, "XXXXXX");
  354.             mktemp(name);
  355.  
  356.             if ((infile = fopen(name, "w")) == NULL) {
  357.                 sprintf(buf, "art: unable to open temporary file %s.\n", name);
  358.                 fatal(buf);
  359.             }
  360.  
  361.             prepro(av[1], infile);
  362.  
  363.             fclose(infile);
  364.         } else
  365.             strcpy(name, av[1]);
  366.     }
  367.  
  368.     if (!standardin) {
  369. #ifdef MSC
  370.         if ((infile = freopen(name, "rt", stdin)) == NULL) {
  371. #else
  372.         if ((infile = freopen(name, "r", stdin)) == NULL) {
  373. #endif
  374.             sprintf(buf, "art: unable to open file %s.\n", av[1]);
  375.             fatal(buf);
  376.         }
  377.     }
  378.  
  379.     /*
  380.      * initialise variable symbol table
  381.      */
  382.     e = (expression *)smalloc(sizeof(expression));
  383.     e->type = EXP_INT;
  384.     e->u.i = 'x';
  385.     defvar("x", e);
  386.  
  387.     e = (expression *)smalloc(sizeof(expression));
  388.     e->type = EXP_INT;
  389.     e->u.i = 'y';
  390.     defvar("y", e);
  391.  
  392.     e = (expression *)smalloc(sizeof(expression));
  393.     e->type = EXP_INT;
  394.     e->u.i = 'z';
  395.     defvar("z", e);
  396.  
  397.     /*
  398.      * initialise object symbol table
  399.      */
  400.     defobj("sphere", SPHERE, (details *)NULL);
  401.     defobj("ellipsoid", ELLIPSOID, (details *)NULL);
  402.     defobj("box", BOX, (details *)NULL);
  403.     defobj("torus", TORUS, (details *)NULL);
  404.     defobj("algebraic", ALGEBRAIC, (details *)NULL);
  405.     defobj("cylinder", CYLINDER, (details *)NULL);
  406.     defobj("cone", CONE, (details *)NULL);
  407.     defobj("superquadric", SUPERQUADRIC, (details *)NULL);
  408.     defobj("ring", RING, (details *)NULL);
  409.     defobj("disk", RING, (details *)NULL);
  410.     defobj("geometry", GEOMETRY, (details *)NULL);
  411.     defobj("polygon", POLYGON, (details *)NULL);
  412.  
  413.     if (preprocess)
  414.         tmpname = name;
  415.     else
  416.         tmpname = (char *)NULL;
  417.  
  418.     yyparse();        /* read in model and set oblist */
  419.  
  420.     if (preprocess)
  421.         unlink(name);
  422.  
  423.     if (!standardin)
  424.         fclose(infile);    /* get rid of temp file (unlinked above) */
  425.  
  426.     getkey();
  427.  
  428.     vexit();
  429.  
  430.     exit(ALLOK);
  431. }
  432.  
  433. /*
  434.  * deflookat
  435.  *
  436.  *    do the perspective and lookat.
  437.  */
  438. deflookat()
  439. {
  440.     perspective(fov, 1.0, 0.0, 1.0e38);
  441.  
  442.     translate(0.0, 0.0, -near);
  443.     up(viewup.x, viewup.y, viewup.z);
  444.     lookat(eye.x, eye.y, eye.z, ref.x, ref.y, ref.z, twist);
  445.  
  446.     lookatdone = TRUE;
  447. }
  448.